//
// Created by XiaoXiu on 2025/5/20.
//

#include "util.h"
#include <windows.h>

uint64_t getUnixTimestampMillis() {
    FILETIME ft;
    GetSystemTimeAsFileTime(&ft);
    ULARGE_INTEGER li;
    li.LowPart = ft.dwLowDateTime;
    li.HighPart = ft.dwHighDateTime;
    return (li.QuadPart - 116444736000000000ULL) / 10000;
}

void generateRandomString(char *str, size_t length) {
    srand(getUnixTimestampMillis());
    const char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    for (size_t i = 0; i < length; i++) {
        str[i] = charset[rand() % (sizeof(charset) - 1)];
    }
    str[length] = '\0'; // Null-terminate the string
}


const char *directionToStr(const Direction dir) {
    switch (dir) {
        case DIR_UP: return "UP";
        case DIR_DOWN: return "DOWN";
        case DIR_LEFT: return "LEFT";
        case DIR_RIGHT: return "RIGHT";
        default: return "NONE";
    }
}


Direction strToDirection(const char *str) {
    if (!str) return DIR_NONE;
    if (strcmp(str, "UP") == 0) return DIR_UP;
    if (strcmp(str, "DOWN") == 0) return DIR_DOWN;
    if (strcmp(str, "LEFT") == 0) return DIR_LEFT;
    if (strcmp(str, "RIGHT") == 0) return DIR_RIGHT;
    return DIR_NONE;
}

PacketType strToPacketType(const char *str) {
    if (!str) return PACKET_TYPE_NONE;
    if (strcmp(str, "INIT") == 0) return PACKET_TYPE_INIT;
    if (strcmp(str, "SYNC") == 0) return PACKET_TYPE_SYNC;
    if (strcmp(str, "FRAME") == 0) return PACKET_TYPE_FRAME;
    if (strcmp(str, "MOVE") == 0) return PACKET_TYPE_MOVE;
    if (strcmp(str, "JOIN") == 0) return PACKET_TYPE_JOIN;
    if (strcmp(str, "EXIT") == 0) return PACKET_TYPE_EXIT;
    if (strcmp(str, "FOOD_CREATE") == 0) return PACKET_TYPE_FOOD_CREATE;
    if (strcmp(str, "FOOD_EATEN") == 0) return PACKET_TYPE_FOOD_EATEN;
    if (strcmp(str, "DIR") == 0) return PACKET_TYPE_DIR;
    if (strcmp(str, "ESC") == 0) return PACKET_TYPE_ESC;
    if (strcmp(str, "NONE") == 0) return PACKET_TYPE_NONE;
    return PACKET_TYPE_NONE;
}

const char *packetTypeToStr(const PacketType type) {
    switch (type) {
        case PACKET_TYPE_DIR: return "DIR";
        case PACKET_TYPE_ESC: return "ESC";
        case PACKET_TYPE_NONE: return "NONE";
        case PACKET_TYPE_INIT: return "INIT";
        case PACKET_TYPE_SYNC: return "SYNC";
        default: return "UNKNOWN";
    }
}

bool is_frame_packet(const Packet *pkt) {
    return pkt->type == PACKET_TYPE_FRAME;
}

void strCopy(const char *src, char *dest, const size_t destSize) {
    if (destSize == 0) return;
    strncpy(dest, src, destSize - 1);
    dest[destSize - 1] = '\0';
}
